/**  
 * @Title: LoginTokenServiceImpl.java
 * @Package org.wk.user.service
 * @Description: TODO【】
 * @author df.w 
 * @date 2018年5月5日 上午10:44:17
 * @version V1.0  
 */ 

package org.wk.user.service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.jsonwebtoken.Claims;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.wk.common.jwt.JwtHelper;
import org.wk.core.common.tool.GeneratorStringUtils;
import org.wk.user.dao.LoginTokenDao;
import org.wk.user.domain.LoginToken;
import org.wk.user.view.Audience;
import org.wk.user.view.TokenModel;
import org.wk.user.view.UserDetailVo;

import com.google.common.base.Strings;

import javax.annotation.Resource;

/**
 * @ClassName	: LoginTokenServiceImpl
 * @Package		：org.wk.user.service
 * @Author df.w 
 * @Create Time	：2018年5月5日 上午10:44:17
 * @Description	: 
 */
@Service
public class LoginTokenServiceImpl implements LoginTokenService {

	private static long TOKEN_EXPIRES_HOUR = 72;

	@Autowired
	private LoginTokenDao loginTokenDao;

	@Resource
	private RedisTemplate<String, TokenModel> redisTemplate;

	@Autowired
	private Audience audience;


	/* (非 Javadoc)
	 * <p>Title: generatorToken</p>
	 * <p>Description: </p>
	 * @param userId
	 * @param nickName
	 * @param headSculpture
	 * @return
	 * @see org.wk.user.service.LoginTokenService#generatorToken(java.lang.String, java.lang.String, java.lang.String)
	 */

	@Override
	public String generatorToken(String userId, String nickName, String headSculpture) {
		if (Strings.isNullOrEmpty(userId)||Strings.isNullOrEmpty(nickName)||Strings.isNullOrEmpty(headSculpture)) {
			return null;
		}
		
		String token = GeneratorStringUtils.uuidStr();
		
		LoginToken loginToken = loginTokenDao.findByToken(token);
		
		if (null==loginToken) {
			loginToken = new LoginToken();
		}
		
		loginToken.setToken(token);
		loginToken.setUserId(userId);
		loginToken.setNickName(nickName);
		loginToken.setHeadSculpture(headSculpture);
		
		DateTime now = new DateTime();
		now = now.plusDays(3);
		loginToken.setExpireTime(now.toDate());
		
		loginTokenDao.saveOrUpdate(loginToken);

		return token;
	}

	/* (非 Javadoc)
	 * <p>Title: getLoginInfoByToken</p>
	 * <p>Description: </p>
	 * @param token
	 * @return
	 * @see org.wk.user.service.LoginTokenService#getLoginInfoByToken(java.lang.String)
	 */

	@Override
	public UserDetailVo getLoginInfoByToken(String token) {
		// TODO Auto-generated method stub
		if (Strings.isNullOrEmpty(token)) {
			return null;
		}
//		LoginToken loginToken = loginTokenDao.findByTokenAndExpireTimeGreaterThan(token,new Date());
		TokenModel tokenModel = this.getToken(token);
		if (!checkToken(tokenModel)) {
			return null;
		}

		String userId = tokenModel.getUserId();
		UserDetailVo userDetailVo = new UserDetailVo();
		userDetailVo.setId(userId);
		Map<String, Object> userInfo = new HashMap<>();
		userInfo.put("userId", userId);
		userDetailVo.setData(userInfo);
		//subAccountService.loginAccountHandler(userId);
		return userDetailVo;
	}

	/**
	 * 创建一个token关联上指定用户
	 *
	 * @param userId 指定用户的id
	 * @return 生成的token
	 */
	@Override
	public TokenModel createToken(String userId) {

		TokenModel tokenModel = new TokenModel();

		tokenModel.setUserId(userId);
		String nonce = GeneratorStringUtils.uuidStr();
		String jwtToken = JwtHelper.createJWT("",
				userId,
				"",
				nonce,
				audience.getClientId(),
				audience.getName(),
				audience.getExpiresSecond()*1000,
				audience.getBase64Secret());
		tokenModel.setToken(jwtToken);
		redisTemplate.opsForValue().set(userId,tokenModel,TOKEN_EXPIRES_HOUR,TimeUnit.HOURS);
		return tokenModel;
	}

	/**
	 * 检查token是否有效
	 *
	 * @param model token
	 * @return 是否有效
	 */
	@Override
	public boolean checkToken(TokenModel model) {
		if (model == null) {
			return false;
		}
		TokenModel token = redisTemplate.opsForValue().get(model.getUserId());
		if (token==null || Strings.isNullOrEmpty(token.getToken()) || !token.getToken().equals(model.getToken())) {
			return false;
		}
		return true;
	}

	/**
	 * 从字符串中解析token
	 *
	 * @param authentication 加密后的字符串
	 * @return
	 */
	@Override
	public TokenModel getToken(String authentication) {
		Claims claims =JwtHelper.parseJWT(authentication,audience.getBase64Secret());
		if (claims==null || claims.get("userId")==null) {
			return null;
		}
		String userId = claims.get("userId").toString();
		TokenModel tokenModel = new TokenModel();
		tokenModel.setUserId(userId);
		tokenModel.setToken(authentication);
		return tokenModel;
	}

	/**
	 * 清除token
	 *
	 * @param userId 登录用户的id
	 */
	@Override
	public void deleteToken(String userId) {
		redisTemplate.delete(userId);
	}

}
